﻿using Learn.Net8.Common.Caches;
using Learn.Net8.Common.Core;
using Learn.Net8.Common.Options;
using Learn.Net8.Extension.Redis;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Learn.Net8.Extension.ServiceExtensions
{
    public static class CacheSetup
    {
        /// <summary>
        /// 统一注册缓存
        /// </summary>
        /// <param name="services"></param>
        public static void AddCacheSetup(this IServiceCollection services)
        {
            // 取用 App.GetOptions<RedisOptions>() 读取配置文件
            var cacheOptions = App.GetOptions<RedisOptions>();
            // 如果开启了Redis缓存
            if (cacheOptions.Enable)
            {
                // 配置启动Redis服务
                // 虽然可能影响项目启动速度，但是不能在运行的时候报错，所以是合理的
                services.AddSingleton<IConnectionMultiplexer>(sp =>
                {
                    //获取连接字符串
                    var configuration = ConfigurationOptions.Parse(cacheOptions.ConnectionString, true);
                    configuration.ResolveDns = true;
                    return ConnectionMultiplexer.Connect(configuration);
                });
                // 使用单例模式，初始化Redis连接池
                services.AddSingleton<ConnectionMultiplexer>(p => p.GetService<IConnectionMultiplexer>() as ConnectionMultiplexer);

                // 使用 Redis 的分布式缓存
                // 核心在如下语句，通过对 IDistributedCache 的实现类 RedisCacheImpl 进行注册
                // services.Add(ServiceDescriptor.Singleton<IDistributedCache, RedisCacheImpl>());
                services.AddStackExchangeRedisCache(options =>
                {
                    options.ConnectionMultiplexerFactory = () => Task.FromResult(App.GetService<IConnectionMultiplexer>(false));
                    if (!string.IsNullOrEmpty(cacheOptions.InstanceName)) options.InstanceName = cacheOptions.InstanceName;
                });
                // 注册 RedisBasketRepository 服务
                services.AddTransient<IRedisBasketRepository, RedisBasketRepository>();
            }
            else  // 如果没有开启Redis缓存
            {
                // 使用内存缓存
                services.AddMemoryCache();
                // 使用分布式内存缓存
                // 核心在如下语句，通过对 IDistributedCache 的实现类 MemoryDistributedCache 进行注册
                // services.TryAdd(ServiceDescriptor.Singleton<IDistributedCache, MemoryDistributedCache>());
                services.AddDistributedMemoryCache();
            }

            // 注册缓存服务
            services.AddSingleton<ICaching, Caching>();
        }
    }
}
